home *** CD-ROM | disk | FTP | other *** search
- /*************************************************************************
-
- NAME
-
- xref -- make list of all words and a file and the line numbers of
- their occurrences, excluding C keywords, words within
- quotation marks, and words within C comment markers, unless
- overridden.
-
- USAGE
-
- xref <input >output -k -q -c
-
- where -k causes inclusion of C keywords
- -q causes inclusion of words within quotes (")
- -c causes inclusion of words within C comment markers
-
- DESCRIPTION
-
- A "word" is a string of letters and digits beginning with a letter.
-
- AUTHOR Philip T. Ansteth
- DATE December 6, 1985
- CLIENT ANSTETH RESEARCH
- P.O. Box 35882
- Tulsa, Ok.
-
-
- CALLED FUNCTIONS
-
- getmem -- gets memory from system pool
-
-
-
- LINKAGE INFORMATION
-
- The link command from the CLI is
-
- alink with xref.lnk
-
- The file alink.lnk must contain:
-
- FROM Lstartup.obj, *
- df1:cs/xref.o, *
- df1:cs/getword.o, *
- df1:cs/getch.o, *
- df1:cs/type.o, *
- df1:cs/strsave.o
- TO df1:cs/xref
- LIBRARY lc.lib, df1:lib/amiga.lib
- MAP :nil
-
-
-
-
- **************************************************************************/
-
- #include <stdio.h>
-
- /* define a template of a struct of type tnode */
- /* This type will contain info. about each word encountered */
- struct tnode {
- char *word; /* pointer to text string */
- int count; /* number of occurrences */
- int linenum; /* first line number */
- struct tnode *left; /* pointer to left child */
- struct tnode *right; /* pointer to right child */
- struct lnode *next; /* pointer to line number list */
- };
-
- /* define a template of a struct of type lnode */
- /* This type will contain line numbers */
- struct lnode {
- int linenum; /* line number */
- struct lnode *next; /* pointer to descendent */
- };
-
- /* global values for determining when to do line feed on line number list*/
- #define MAXPER 10
- int lnktrl;
-
- char *keytab[] = {
- "auto",
- "break",
- "case",
- "char",
- "continue",
- "default",
- "do",
- "double",
- "else",
- "entry",
- "extern",
- "float",
- "for",
- "goto",
- "if",
- "int",
- "long",
- "register",
- "return",
- "short",
- "sizeof",
- "static",
- "struct",
- "switch",
- "typedef",
- "union",
- "unsigned",
- "while"
- };
-
- #define NKEYS (sizeof(keytab) / sizeof(keytab[0]))
-
- #define MAXWORD 20 /* max no. of chars in a word */
- #define LETTER 'a' /* code indicating an alpha character, a-z,A-Z */
- #define DIGIT '0' /* code indicating a digit, 0-9 */
-
- int incomments=0; /*global flag indicating whether within C comment markers */
- int inquotes=0; /*global flag indicating whether within quotation marks */
-
- /* mainline */
- main(argc,argv)
- int argc;
- char *argv[];
- {
- struct tnode *root, *tree(); /* root is a pointer to a structure
- of type tnode; tree is a function
- returning a pointer to a structure
- of type tnode */
- char word[MAXWORD]; /* character array for storing word */
- int t; /* receives type code from getwordl */
- int lnumber=1; /* line number counter */
- char *s; /* command line argument receiver */
- int kwords=0,quotes=0,comments=0; /* flags for command line options */
- int useflag=0; /* flag stating whether this word is used */
-
-
- while (--argc > 0 && (*++argv)[0] == '-') /* scan for optional flags */
- for (s = argv[0]+1; *s != '\0' ; s++) /* scan for string terminator.*/
- switch(*s) { /* s is initialized with*/
- case 'k': /* pointer to 1st character*/
- kwords = 1; /* after that pointed to by*/
- break; /* argv */
- case 'q':
- quotes = 1;
- break;
- case 'c':
- comments = 1;
- break;
- default:
- printf("xref: illegal option %c\n", *s);
- argc = 1; /* make sure error message will be printed */
- break;
- }
- if (argc != 0) {/* expect argc to equal 0 at end of previous while
- and argv now is address containing pointer to
- last argument */
- printf("Usage: xref <input >output -k -q -c\n");
- exit(1);
- }
-
- root=NULL; /* first time root is NULL */
- /* read each word in file and install it somewhere in the tree */
- while ((t = getwordl(word,MAXWORD,&lnumber)) != EOF)
- if (t == LETTER) {
- useflag = 1;
- /* are we excluding C keywords? */
- if (kwords == 0)
- if (binary(word,keytab,NKEYS) >= 0)
- useflag = 0;
- /* are we excluding words within quotes? */
- if (quotes == 0)
- if (inquotes == 1)
- useflag = 0;
- /* are we excluding words within comment markers? */
- if (comments == 0)
- if (incomments == 1)
- useflag = 0;
- if (useflag == 1)
- root = tree(root,word,lnumber);
- }
- if(incomments == 1)
- printf("xref: WARNING--unbalanced C comment markers\n");
- if(inquotes == 1)
- printf("xref: WARNING--unbalanced quotation marks\n");
-
- treeprint(root); /* print out the tree */
- }
- /*************************************************************************/
- /* function to install word in tree */
- struct tnode *tree(p,w,lnumber) /* returns pointer to a tnode struct */
- struct tnode *p; /* UPDATE pointer to tnode structure */
- char *w; /* INPUT pointer to a char string containing word */
- int lnumber; /* INPUT linenumber where word occurs */
- {
- struct tnode *talloc(); /* talloc is a function returning a pointer
- to a structure of type tnode */
- char *strsave(); /* strsave is a function returning a point
- to a character string */
- int cond; /* holds result of strcmp */
- struct lnode *list(); /* function returning pointer to lnode struct*/
-
-
- if (p == NULL) { /* has a new word arrived? */
- p = talloc(); /* allocate space &
- return pointer for a new node */
- p->word = strsave(w); /* fill in word */
- p->linenum = lnumber; /* fill in first line number */
- p->count = 1; /* initialize counter */
- p->left = p->right = p->next = NULL; /* set pointers to NULL */
- }
-
- else if ((cond = strcmp(w, p->word)) == 0) { /* is it a repeated word? */
- p->count++; /* increment counter */
- p->next=list(p->next,lnumber); /* install line no. at end */
- }
-
- else if (cond < 0) /* are there more to look at in left subtree? */
- p->left = tree(p->left, w,lnumber); /* install it somewhere to the left */
-
- else /* greater into right subtree */
- p->right = tree(p->right,w,lnumber);
- return(p); /* return pointer */
- }
-
- /*************************************************************************/
- /* function to install line number at end of list */
- struct lnode *list(lp,lnumber)
- struct lnode *lp; /* UPDATE: pointer to lnode struct */
- int lnumber; /* INPUTE: line number where word occurred */
- {
- struct lnode *lalloc(); /* function returning pointer to lnode struct */
-
-
- if(lp == NULL) { /* is this the end of the list? */
- lp = lalloc(); /* get pointer for next node */
- lp->linenum = lnumber; /* install line number there */
- lp->next = NULL; /* fill in NULL to end list there */
- }
- else
- lp->next=list(lp->next,lnumber); /* go on to next node */
-
- return(lp); /* return pointer for installation by caller */
-
- }
-
-
- /*************************************************************************/
- /* function to print tree recursively,
- using "left tree" order */
- treeprint(p)
- struct tnode *p; /* INPUT: pointer to tnode struct */
- {
- static int ifirst=1; /* first time flag */
-
-
-
- if(ifirst == 1) { /* print headers on first time through */
- ifirst = 0;
- printf("\n");
- printf("Cross Reference Utility\n\n");
- printf("Count Word Lines where occurring\n\n");
- }
-
- if(p != NULL) {
- treeprint(p->left); /* do left branch first */
- printf("%5d %-20.20s %4d", /* print current data */
- p->count,p->word,p->linenum);
- lnktrl=1; /* set line no. counter to 1 */
- listprint(p->next); /* print line occurrences */
- treeprint(p->right); /* now do right branch */
- }
- }
-
- /*************************************************************************/
- /* function to print out line numbers of word occurrences */
- listprint(lp)
- struct lnode *lp; /* INPUT: pointer to lnode struct */
- {
-
- if(lp != NULL) {
- if(lnktrl < MAXPER) {
- printf(" %d",lp->linenum);
- lnktrl++;
- }
- else {
- printf("\n %d",lp->linenum);
- lnktrl=1;
- }
- listprint(lp->next);
- }
- else
- printf("\n");
- }
-
- /*************************************************************************/
- /* function to allocate memory for tnode struct */
- struct tnode *talloc() /* get memory for structure and return
- pointer of the correct type */
- {
- char *getmem(); /* getmem is a subroutine returning
- a pointer to a character */
-
-
- return(
- (struct tnode *) /* coerce getmem to a pointer t a tnode struct */
- getmem(sizeof(struct tnode)) /* get memory for a tnode structure */
- );
- }
-
- /*************************************************************************/
- /* function to allocate memor∙ for lnode struct */
- struct lnode *lalloc()
- {
- char *getmem();
-
-
- return( (struct lnode *) getmem(sizeof(struct lnode)));
- }
-
- /*************************************************************************/
- /* function to get next word from input */
- getwordl(w,lim,plnumber) /* get next word from input */
- char *w; /* OUTPUT: pointer to word found */
- int lim; /* INPUT: maximum word length */
- int *plnumber; /* UPDATE: line number where word found */
- /* returns LETTER when word found */
- /* otherwise returns most recent non-alpha char */
- {
- int c,t; /* receive output of getch and type functions */
-
-
-
- if ( (c = getch()) == '"')
- inquotes = !inquotes;
- ungetch(c);
-
- if (incomments == 0) {
- c = getch();
- t = getch();
- if (c == '/' && t == '*')
- incomments = 1;
- ungetch(t);
- ungetch(c);
- }
- else if (incomments == 1) {
- c = getch();
- t = getch();
- if (c == '*' && t == '/')
- incomments = 0;
- ungetch(t);
- ungetch(c);
- }
-
-
- if(type(c = *w++ = getch()) != LETTER) { /* is first character non-alpha? */
- *w = '\0'; /* second character of w is string terminator */
-
- if( c == '\n')
- *plnumber += 1;
- return(c); /* return character in c too */
- }
- while (--lim > 0) { /* check subsequent characters up to lim */
- t = type(c = *w++ = getch()); /* put alpha or num. in w and t */
- if (t != LETTER && t != DIGIT) {
- ungetch(c);
- break;
- }
- }
- *(w-1) = '\0'; /* reached end, so back up and put in string delimiter */
-
-
- return(LETTER);
-
- }
-
-
- /*************************************************************************/
- binary(word,tab,n) /* find word in tab[0]. . .tab[n-1] */
- char *word;
- char *tab[]; /* tab is a table of pointers */
- int n;
- {
- int cond;
- int low;
- int high;
- int mid;
-
- low = 0;
- high = n-1;
-
- while(low <= high) {
- mid = (high+low) / 2;
- if ((cond=strcmp(word,tab[mid])) < 0)
- high = mid-1;
- else if (cond > 0)
- low = mid+1;
- else
- return(mid);
- }
- return(-1);
- }
-